TCP hole punching

TCP hole punching is a commonly-used NAT traversal technique, for sending 2-way messages between nodes in an Internet computer network. The term "NAT traversal" is a general term for techniques that establish and maintain TCP/IP network and/or TCP connections traversing network-address-translation (NAT) gateways.

NAT traversal techniques are typically required for client-to-client networking applications, especially peer-to-peer and Voice-over-IP (VoIP) deployments.

Contents

Description

NAT traversal, through TCP hole punching, is a method for establishing bidirectional TCP connections between Internet hosts in private networks using NAT. It does not work with all types of NATs, as their behavior is not standardized.

Network Drawing

  Peer A ←→ Gateway A ← .. Network .. → Gateway B ←→ Peer B  

Types of NAT

The availability of the TCP-hole-punching technique depends on the type of computer port allocation used by the NAT. When two peers, A and B, instantiate TCP connections by binding to local ports Pa and Pb, respectively, they need to know the remote endpoint NAT port in order to make the connection.

A NAT port allocation can be one of the two:

Connection matrix representing the different cases:

A predictable A non-predictable
B predictable YES YES
B non-predictable YES NO
  • YES: the connection will work all the time
  • NO: the connection will almost never work

Techniques

Methods of port Prediction

Sequence/Acknowledgment numbers negotiation

Because both parties are connecting to each other (e.g., 2x CONNECT(), no LISTEN(), ACCEPT(), etc.), to generate OUTBOUND traffic, there is however a problem with:

  • TCP Sequence numbers
  • Acknowledgment numbers

The required state is just like after the three-way-handshake: Each host must have an acknowledge number == other sequence number + 1. This is achieved through Sequence and Acknowledgement Number coordination.

Low TTL Value determination

Because some packets (syn, rst) MUST not reach the other host, as it would corrupt the connection setup in progress, then there is the need to apply a trick with the TTL values. The Low TTL value is used to generate outbound packets that will open up the NAT, but will never reach the other host.

The Low TTL is calculated as follow:

  • Send SYN with TTL of i=1
  • Wait for ICMP TTL Exceeded message
  • i = i + 1, loop

Loop until "ICMP TTL Exceeded" messages are no longer received. The own NAT host has been traversed. The LOW TTL Value = i + 1.

If the NAT host supports "ICMP TTL Exceeded" messages to internal hosts, then the RST reply from buddy can be inspected. The LOW TTL Value = i - 1.

OS Support

See also